﻿using System;
using System.Reflection;
using SimpleOrmCFPC.Helpers;

namespace SimpleOrmCFPC.Core.Model
{
   public static class EntityExtensions
   {
      public static bool IsEntity(this Type type)
      {
         return type.HasAttribute<EntityAttribute>();
      }

      public static string GetEntityName(this Type type)
      {
         var tableName = type.Attribute<EntityAttribute>().TableName;
         if (tableName == EntityAttribute.TYPE_NAME)
            return type.Name;
         return tableName;
      }

      public static PropertyInfo GetPrimaryKey(this Type entity)
      {
         foreach (var property in entity.GetProperties())
         {
            if (property.HasAttribute<PrimaryKeyAttribute>())
               return property;
         }
         throw new Exception("No primary key found");
      }

      public static bool IsManyToOne(this PropertyInfo property)
      {
         return property.PropertyType.HasAttribute<EntityAttribute>();
      }

      public static string GetColumnName(this PropertyInfo property)
      {
          return property.IsManyToOne() ? property.Name + "Id" : property.Name;
      }

      public static bool IsPrimaryKey(this PropertyInfo property)
      {
          return property.HasAttribute<PrimaryKeyAttribute>();
      }

      public static int GetMaxLength(this PropertyInfo property)
      {
          return property.HasAttribute<MaxLengthAttribute>() ? property.Attribute<MaxLengthAttribute>().Length : 255;
      }

      public static bool IsNotNull(this PropertyInfo property)
      {
          return property.HasAttribute<NotNullAttribute>();
      }

      public static T GetPrimaryKeyValue<T>(this object o)
      {
         return (T)GetPrimaryKeyValue(o);
      }

      public static object GetPrimaryKeyValue(this object o)
      {
         var type = o.GetType();
         if (!type.IsEntity())
            throw new Exception("This object is not an entity : " + type.Name);
         return type.GetPrimaryKey().GetValue(o, new object[0]);
      }
   }
}
